package com.hfkh.util;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.*;


public class BaseDAO {
    private Connection connection;
    private PreparedStatement pstm;
    private ResultSet resultSet;
    private static String JDBC_DRIVER;
    private static String JDBC_URL;
    private static String JDBC_NAME;
    private static String JDBC_PASSWORD;
    static {//当基本的DAO类加载时，我们取出文件中存储的有关驱动连接的数据
        Properties properties = new Properties();
        InputStream inputStream = BaseDAO.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            properties.load(inputStream);
            JDBC_DRIVER = properties.getProperty("jdbc_driver");
            JDBC_URL = properties.getProperty("jdbc_url");
            JDBC_NAME = properties.getProperty("jdbc_name");
            JDBC_PASSWORD = properties.getProperty("jdbc_password");
        } catch (IOException e) {
            System.out.println("加载文件出错！");
            e.getMessage();
        }finally {
            if (inputStream != null){
                try {
                    inputStream.close();
                    inputStream = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    static {//加载驱动
        try {
            Class.forName(JDBC_DRIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public Connection getConnection(){
        try {
            this.connection = DriverManager.getConnection(JDBC_URL);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return this.connection;
    }
    public void closeAll(){
        if (this.resultSet != null){
            try {
                this.resultSet.close();
                this.resultSet = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (this.pstm != null){
            try {
                this.pstm.close();
                this.pstm = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (this.connection != null){
            try {
                this.connection.close();
                this.connection = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //升级
    public <T> List<T> queryForList(String sql,Object[] params,Class<T> clazz){
        List<T> dataList = new ArrayList<>();
        connection = getConnection();
        try {
            pstm = this.connection.prepareStatement(sql);
            if (params != null){
                for (int i = 0,len = params.length; i < len; i++) {
                    pstm.setObject(i + 1,params[i]);
                }
            }
            resultSet = pstm.executeQuery();
            while (resultSet.next()){
                T entity = clazz.getDeclaredConstructor().newInstance();
                ReflectionUtil.setPropToBeanFromResultSet(entity,resultSet);
                dataList.add(entity);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return dataList;
    }
    public <T> T queryForObject(String sql,Object[] params,Class<T> clazz){
        T target = null;
        List<T> dataList = queryForList(sql,params,clazz);
        if (dataList != null && dataList.size() == 1){
            target = dataList.get(0);
        }
        return target;
    }
    @Deprecated
    public List<Map<String,Object>> executeQuery(String sql,Object[] params){
        //执行查询语句，返回一个list，由于不知道字段名，只能用map集合再包裹一层
        List<Map<String,Object>> dataList = new ArrayList<>();
        this.connection = getConnection();
        Map<String,Object> colMap = null;
        try {
            this.pstm = this.connection.prepareStatement(sql);
            if (params != null){
                for (int i = 0,len = params.length; i < len; i++) {
                    pstm.setObject((i + 1),params[i]);
                }
            }
            this.resultSet = pstm.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int cloNums = rsmd.getColumnCount();
            while (resultSet.next()){
                colMap = new HashMap<>();
                for (int i = 0; i < cloNums; i++) {
                    String colLabel = rsmd.getColumnLabel(i + 1);
                    Object colValue = resultSet.getObject(colLabel);
                    colMap.put(colLabel,colValue);
                }
                dataList.add(colMap);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll();
        }
        return dataList;
    }
    public int executeUpdate(String sql,Object[] params){
        int rows = 0;
        this.connection = getConnection();
        try {
            pstm = this.connection.prepareStatement(sql);
            if (params != null){
                for (int i = 0,len = params.length; i < len; i++) {
                    pstm.setObject((i+1),params[i]);
                }
            }
            rows = pstm.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll();
        }
        return rows;
    }
}
